package com.deepclassifieds.daas.ql.sql;

import java.io.ByteArrayInputStream;

import org.antlr.runtime.ANTLRInputStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.tree.CommonTreeNodeStream;
import org.antlr.runtime.tree.Tree;

import com.deepclassifieds.daas.common.Reject;
import com.deepclassifieds.daas.ql.DaasqlLexer;
import com.deepclassifieds.daas.ql.DaasqlParser;

public class DaasqlToSQL {
	
    public static String toSQL(String daasql) throws Exception {
    	
        ByteArrayInputStream daasqlStream = new ByteArrayInputStream( daasql.getBytes() );

        ANTLRInputStream source = new ANTLRInputStream( daasqlStream );
        DaasqlLexer lexer = new DaasqlLexer( source );
        CommonTokenStream tokens = new CommonTokenStream( lexer );

        DaasqlParser parser = new DaasqlParser( tokens );
        Tree ast = (Tree) parser.where().getTree();
       

        CommonTreeNodeStream nodes = new CommonTreeNodeStream( ast );
        StringBuilder sb = new StringBuilder(daasql.length() * 3);
        traverseTree(sb, ast);

//        Reader templatesIn = new InputStreamReader( getClass().getResourceAsStream( "/templates/sparql.stg" ) );
//        StringTemplateGroup templates = new StringTemplateGroup( templatesIn, DefaultTemplateLexer.class );

//        DaasqlWalker walker = new SparqlWalker( nodes );
//        walker.setTemplateLib( templates );
        
//        return walker.query().toString();
        return sb.toString();
    }
    
    private static void traverseTree(StringBuilder sb, Tree ast) {
    	assert sb != null;
    	assert ast != null;
    	
//    	if(sb.length() > 0) sb.append(" ");
//    	sb.append(ast.getText()).append("-").append(ast.getType());
        	int count = ast.getChildCount();
        	for(int i = 0; i < count; ++i) {
        		if(i > 0) System.out.print(' ');
        		System.out.print(ast.getChild(i).getText() + ":" + ast.getChild(i).getType());
        	}
        	System.out.println();
        	{
        		int i = 0;
        		Tree op = ast.getChild(i++);
        		switch(op.getType()) {
        		case DaasqlLexer.EQ: {
        			Reject.ifFalse(DaasqlLexer.LPAR == ast.getChild(i++).getType());
        			String name = ast.getChild(i++).getText();
        			Reject.ifFalse(DaasqlLexer.COMMA == ast.getChild(i++).getType());
        			String value = ast.getChild(i++).getText();
        			Reject.ifFalse(DaasqlLexer.RPAR == ast.getChild(i++).getType());
        			sb.append(name).append(" = ").append(value);
        		}
        		break;
        		case DaasqlLexer.NE: {
        			Reject.ifFalse(DaasqlLexer.LPAR == ast.getChild(i++).getType());
        			String name = ast.getChild(i++).getText();
        			Reject.ifFalse(DaasqlLexer.COMMA == ast.getChild(i++).getType());
        			String value = ast.getChild(i++).getText();
        			Reject.ifFalse(DaasqlLexer.RPAR == ast.getChild(i++).getType());
        			sb.append(name).append(" <> ").append(value);
        		}
        		break;
        		case DaasqlLexer.AND: {
        			Reject.ifFalse(DaasqlLexer.LPAR == ast.getChild(i++).getType());
        			sb.append("("); 
        			traverseTree(sb, ast.getChild(i++));
        			sb.append(")"); 
        			Reject.ifFalse(DaasqlLexer.COMMA == ast.getChild(i++).getType());
        			sb.append(" AND "); 
        			sb.append("("); 
        			traverseTree(sb, ast.getChild(i++));
        			sb.append(")"); 
        			Reject.ifFalse(DaasqlLexer.RPAR == ast.getChild(i++).getType());
        		}
        		break;
        		}
        	}
    }
}
